Technote 1110

Supporting Plug-in Renderers in QuickDraw3D 1.5.3 Applications


ñ⁄éü

ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉTÉ|Å[Ég

óvñÒ


ÉTÅ[ÉhÉpÅ[ÉeÉBêªÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉTÉ|Å[ÉgÇÕ QuickDraw3D 1.5 ÇÃêVã@î\Ç≈Ç∑ÅBDZÇà TECHNOTE Ç≈ÇÕÅAQuickDraw3D 1.5 ÇÃÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™ÉvÉâÉOÉCÉìÇìKêÿÇ…ÉTÉ|Å[ÉgÇ∑ÇÈï˚ñ@Çê‡ñæÇµÇ‹Ç∑ÅBÉvÉâÉOÉCÉìÇÃÉTÉ|Å[ÉgÇí«â¡Ç∑ÇÈDZÇΔÇÕîÒèÌÇ…ä»íPÇ≈ÅAǪÇÍÇ…ÇÊǡǃÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕåªç›óòópâ¬î\ǻLJÇÃÇÕÇ‡ÇøÇÎÇÒÅAè´óàÇÃÉTÅ[ÉhÉpÅ[ÉeÉBêªÉvÉâÉOÉCÉìÇLJóòópÇ≈Ç´ÇÈÇÊǧDžǻÇËÇ‹Ç∑ÅB

DZÇà TECHNOTE ÇÕÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉTÉ|Å[ÉgÇíÒãüÇ∑ÇÈDZÇΔÇ…ãªñ°ÇÃdžÇÈÉfÉxÉçÉbÉpÇÃï˚ÇÃÇΩÇflÇÃLJÇÃÇ≈Ç∑ÅBÅw3D Graphics Programming With QuickDraw 3DÅx(Addison-Wesley äß) DždžÇÈÇÊǧǻ QD3D ÇÃÉvÉçÉOÉâÉ~ÉìÉOíméØÇ™ëOíÒÇΔǻǡǃǢÇÈDZÇΔÇÇ≤óπè≥Ç≠ÇæÇ≥Ç¢ÅB


ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉTÉ|Å[Ég

ÉAÉvÉäÉPÅ[ÉVÉáÉìÇê›åvÇ∑ÇÈç€Ç…ëÂêÿÇ»ÇÃÇÕÅuÉCÉìÉ^ÉâÉNÉfÉBÉuÅvÇ»ê´î\ÇéùǬÉåÉìÉ_Éâ (ó·Ç¶ÇŒ Apple ÇÃÉèÉCÉÑÉtÉåÅ[ÉÄÉåÉìÉ_ÉâÇ®ÇÊÇ—ÉCÉìÉ^ÉâÉNÉeÉBÉuÉåÉìÉ_Éâ) ÇΔÅAǪÇÃëºÇÃÉåÉìÉ_Éâ (LightWork Design ÇÃÉåÉCÉgÉåÅ[ÉT) ÇΔÇÃà·Ç¢Ççló∂Ç…ì¸ÇÍÇÈDZÇΔÇ≈Ç∑ÅBLightWork Design Çà QD3D ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃè⁄ç◊DžǬǢǃÇÕÅAhttp://www.lightwork.com ÇéQèΔǵǃÇ≠ÇæÇ≥Ç¢ÅB

ÉCÉìÉ^ÉâÉNÉeÉBÉuÇ»ê´î\ÇéùÇΩǻǢÉåÉìÉ_ÉâÇÃèÍçáÅAǪÇÃÉåÉìÉ_ÉâÇ…ÇÕèoóÕêÍópÇÃêVǵǢÉEÉCÉìÉhÉEÇçÏê¨ÇµÇƒó^ǶÅAǪÇÃä‘ÇÕÉCÉìÉ^ÉâÉNÉeÉBÉuÇ»ê´î\ÇéùǬï ÇÃÉåÉìÉ_ÉâÇÃä«óùâ∫ÇÃÉEÉCÉìÉhÉEÇ≈ÅAÉÜÅ[ÉUÇ™ÉVÅ[ÉìÇÃÉGÉåÉÅÉìÉgÇëÄçÏÇ≈Ç´ÇÈÇÊǧDžÇ∑ÇÈÇΔÇÊÇ¢Ç≈ǵÇÂǧÅBÉåÉìÉ_ÉâÇ™ÉCÉìÉ^ÉâÉNÉeÉBÉuÇ»ê´î\ÇÉTÉ|Å[ÉgǵǃǢÇÈǩǫǧǩÇÕÅAéüÇÃÇÊǧDž Q3Renderer_IsInteractive API ÉRÅ[ÉãÇégǡǃí≤Ç◊ÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅB

/*
* Q3Renderer_IsInteractive
* ÉåÉìÉ_ÉâÇ™ÉCÉìÉ^ÉâÉNÉeÉBÉuÇ…égópâ¬î\ǩǫǧǩÇí≤Ç◊ÇÈ
*/
TQ3Boolean Q3Renderer_IsInteractive(TQ3RendererObject renderer);


é©ï™Ç≈ÇÕÉåÉìÉ_ÉâÇèëǩǻǢDžÇπÇÊÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÉTÉ|Å[ÉgÇ∑Ç◊Ç´Ç»ÇÃÇÕñæÇÁÇ©Ç≈Ç∑ÅBÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇê≥ǵÇ≠ÉTÉ|Å[ÉgÇ∑ÇÈÇΩÇflÇ…ÇÕÅAÇ¢Ç≠ǬǩÇÃDZÇΔÇÇµÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅB
  • égópâ¬î\Ç»ÉåÉìÉ_ÉâÇ QD3D Ç…ñ‚Ç¢çáÇÌÇπÇÈÅB
  • égópâ¬î\Ç»ÉåÉìÉ_ÉâÇÃÉäÉXÉgÇç\ízǵÅAÉÜÅ[ÉUÇ…ëIëÇ≥ÇπÇÈÅB
  • ÉåÉìÉ_ÉâÇ™ÉCÉìÉ^ÉâÉNÉeÉBÉuÇ©Çí≤Ç◊ÇÈÅB
  • ÉÜÅ[ÉUÇÃëIëÇ…âûÇ∂ǃÅAégópÇ∑ÇÈÉåÉìÉ_ÉâÇê›íËÇ∑ÇÈÅB

Ç‹ÇΩÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃãNìÆéûÇ… (ǪÇÍǺÇÍÇÃéÌófiÇ≤ÇΔÇ… 1 å¬Ç∏Ǭ) ÉåÉìÉ_ÉâÇÃÉCÉìÉXÉ^ÉìÉXÇçÏê¨Ç∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBDZÇÍÇÇµÇ»ÇØÇÍnjǻÇÁǻǢóùóRÇÕÅAÉåÉìÉ_ÉâÇÃÉCÉìÉXÉ^ÉìÉXÇîjâÛǵǃǵNjǧÇΔÅAê›íËèÓïÒLJé∏ÇÌÇÍÇÈÇ©ÇÁÇ≈Ç∑ÅBÉåÉìÉ_ÉâÇÃê›íËïœçXÇÃÇΩÇflÇÃÉ_ÉCÉAÉçÉOÇópà”ǵǃÅAêèéûïœçXÇ≈Ç´ÇÈÇÊǧDžÇ∑ÇÈÇ…ÇÕÅAǪÇÃÉåÉìÉ_ÉâÇë∂ë±Ç≥ÇπǃǮÇ≠ïKóvǙdžÇËÇ‹Ç∑ÅB

DZDZÇ≈Ç®å©ÇπÇ∑ÇÈï˚ñ@ÇÕîÒèÌÇ…íPèÉǻLJÇÃÇ≈džÇËÅAäeÉåÉìÉ_ÉâÇ…ÉOÉçÅ[ÉoÉãÇ»ê›íËèÓïÒÇéùÇΩÇπǃǢÇÈÇΩÇflÅAç≈LJÇÊÇ¢ó·ÇΔÇÕǢǶNjÇπÇÒÅBñ{äiìIÇ»ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAÉEÉCÉìÉhÉEÇ≤ÇΔÇ…ÉåÉìÉ_ÉâÇä«óùÇ∑Ç◊Ç´Ç≈ǵÇÂǧÅBǪÇÍÇ…ÇÕ 2 ǬÇÃï˚ñ@ǙdžÇËÇ‹Ç∑ÅB1 ǬÇÕÅAÉEÉCÉìÉhÉEÇ≤ÇΔ (LJǡÇΔê≥ämÇ…ÇÕï`âÊÉRÉìÉeÉLÉXÉgÇ≤ÇΔ) Ç…ï ÅXÇÃÉåÉìÉ_ÉâÇÃÉäÉXÉgÇópà”ǵÅAÉEÉCÉìÉhÉEÇ™ï¬Ç∂ÇÈÇ‹Ç≈ï€éùÇ∑ÇÈï˚ñ@Ç≈Ç∑ÅBLJǧ 1 ǬÇÕ (DZÇÃǟǧǙå¯ó¶Ç™ÇÊÇ¢ÇΩÇflÇ±ÇøÇÁÇÇ®Ç∑Ç∑ÇflǵNjÇ∑Ç™)ÅAÉåÉìÉ_ÉâÇÃê›íËèÓïÒÇíPèÉÇ…ÉLÉÉÉbÉVÉÖǵǃǮÇ≠ï˚ñ@Ç≈Ç∑ (Q3InteractiveRenderer_GetPreferences Ç®ÇÊÇ— Q3InteractiveRenderer_SetPreferences ä÷êîÇégópǵNjÇ∑)ÅB

ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉäÉXÉgÇÃçÏê¨

égópâ¬î\Ç»ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉäÉXÉgÇä‹ÇfiÉÅÉjÉÖÅ[ÇÃçÏê¨ï˚ñ@Çå©ÇƒÇ›Ç‹ÇµÇÂǧÅBÇ‹Ç∏ÅAÉVÉXÉeÉÄÇ…ÉCÉìÉXÉgÅ[ÉãÇ≥ÇÍÇΩÉåÉìÉ_ÉâÇÃÉäÉXÉgÇéÊìæÇµÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅBQD3D.h ÉCÉìÉ^ÉtÉFÅ[ÉXÅEÉtÉ@ÉCÉãÇ…éüÇÃïîï™Ç™Ç†ÇËÇ‹Ç∑ (ÉRÉÅÉìÉgïîï™ÇÕì˙ñ{åÍÇ≈é¶ÇµÇ‹Ç∑)ÅB
/*
* TQ3SubClassData ÇÕÅAì¡íËÇÃêeÇÃÉ^ÉCÉvÇ…ëÆÇ∑ÇÈÉTÉuÉNÉâÉXÇÉIÉuÉWÉFÉNÉg
* ÉVÉXÉeÉÄÇ…ñ‚Ç¢çáÇÌÇπÇÈèÍçáÇ…égópÇ∑ÇÈÅB
*/

typedef struct TQ3SubClassData {
   unsigned long numClasses;  /* êeÉNÉâÉXDždžǡÇΩÉTÉuÉNÉâÉXÉ^ÉCÉvÇÃå¬êî */
   TQ3ObjectType *classTypes; /* ǪÇÃÉNÉâÉXÉ^ÉCÉvÇì¸ÇÍÇΩîzóÒ */
} TQ3SubClassData;


DZÇÃç\ë¢ëÃÇ…ÇÕÅAì¡íËÉ^ÉCÉvÇÃÉNÉâÉXÇÃå¬êîÇΔÅAÉNÉâÉXÉ^ÉCÉvÇï\Ç∑ 4 ï∂éöÇÃéØï éqÇä‹Çfi TQ3ObjectType ÇÃîzóÒÇ™ä‹Ç‹ÇÍÇ‹Ç∑ÅBDZÇÃÉfÅ[É^ç\ë¢ëÃÇÕÅAQ3ObjectHierarchy_GetSubClassData ÇåƒÇ—èoǵǃê›íËǵNjÇ∑ÅB
/*
* êeÉ^ÉCÉvÇΔÅATQ3SubClassData ç\ë¢ëÃÇÃÉCÉìÉXÉ^ÉìÉXÇ™ó^ǶÇÁÇÍÇÈÇΔÅA
* ǪÇÃç\ë¢ëÃÇ…ÅAÉNÉâÉXäKëwíÜÅAêeÉNÉâÉXÇÃíºâ∫ÇÃÉTÉuÉNÉâÉXÇÃå¬êîÇΔ
* ÉNÉâÉXÉ^ÉCÉvÇê›íËÇ∑ÇÈÅBê¨å˜ÇÃèÍçáÇÕ kQ3Success ÇÅAÉGÉâÅ[Ç™ãNDZÇÈÇΔ
* kQ3Failure Çï‘Ç∑ÅB
*
* íçà”: DZÇÃä÷êîÇÕÅAclassTypes îzóÒópÇ…ÉÅÉÇÉäÇäÑÇËìñǃÇÈÅB
* Q3ObjectClass_EmptySubClassData ÇåƒÇ—èoǵǃÅAïKÇ∏DZÇÃÉÅÉÇÉäÇâï˙Ç∑ÇÈDZÇΔÅB
*/
TQ3Status Q3ObjectHierarchy_GetSubClassData(
   TQ3ObjectType objectClassType,
   TQ3SubClassData *subClassData
);


íçà”: DZÇÃåƒÇ—èoǵÇçsǧÇΔÉÅÉÇÉäÇ™äÑÇËìñǃÇÁÇÍÇÈèÍçáǙdžÇËÇ‹Ç∑Ç™ÅAéüÇÃÇÊǧDžäÑÇËìñǃÇÁÇÍÇΩÉÅÉÇÉäÇâï˙Ç∑ÇÈä÷êîÇ™ópà”Ç≥ÇÍǃǢNjÇ∑ÅB


/*
* TQ3SubClassData ç\ë¢ëÃÇÃÉCÉìÉXÉ^ÉìÉXÇ™ó^ǶÇÁÇÍÇÈÇΔÅA
* Q3ObjectClass_GetSubClassData ÇåƒÇ—èoǵǃäÑÇËìñǃÇΩÉÅÉÇÉäÇÇ∑Ç◊ǃâï˙Ç∑ÇÈÅB
*
* íçà”: DZÇÃä÷êîÇÕÅAQ3ObjectClass_GetSubClassData ÇÃåƒÇ—èoǵÇÃå„Ç…ÇÕ
* ïKÇ∏åƒÇ—èoǵǃÅAÉÅÉÇÉäÉäÅ[ÉNÇñhÇÆïKóvǙdžÇÈÅB
*/
TQ3Status Q3ObjectHierarchy_EmptySubClassData(
   TQ3SubClassData *subClassData
);


ÉåÉìÉ_ÉâÉ^ÉCÉvÇÃÉTÉuÉNÉâÉXÇÃÉäÉXÉgÇéÊìæÇµÇΩÇÁ (è„Çà Q3ObjectHierarchy_GetSubClassData ä÷êîÇ… kQ3SharedTypeRenderer Çìnǵǃ)ÅAîzóÒíÜÇÉãÅ[ÉvǵǃÅAèáî‘Ç…îzóÒì‡ÇÃäeÉåÉìÉ_ÉâÇÃÉTÉuÉNÉâÉXÇèàóùÇ∑ÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅB

â∫ÇÃÉRÅ[ÉhÇÃífï–ÇÕÅAÉåÉìÉ_ÉâÇÃÉjÉbÉNÉlÅ[ÉÄÇéÊìæÇµÇÊǧÇΔÇ∑ÇÈLJÇÃÇ≈Ç∑ÅBQD3D ÉVÉXÉeÉÄÇÃäeÉNÉâÉXÇÕå≈óLÇÃÉ^ÉCÉvÇΔÉNÉâÉXñºÇéùǡǃǢNjÇ∑ÅBÉjÉbÉNÉlÅ[ÉÄÇΔǢǧäTîOÇÕêVǵǢLJÇÃÇ≈Ç∑ÅBQD3D É`Å[ÉÄÇ™ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃÉVÉXÉeÉÄÇäJî≠íÜÇ…ÅAÉNÉâÉXñºÇÕÉçÅ[ÉJÉâÉCÉYÇ≈ǴǻǢÇΩÇflÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃÉÜÅ[ÉUÉCÉìÉ^ÉtÉFÅ[ÉXÇ≈égópÇ≈ǴǻǢDZÇΔÇ™ñæÇÁǩDžǻÇËNjǵÇΩÅBǪÇÍÇ≈ÅAåƒÇ—èoǵÇçsǧÉAÉvÉäÉPÅ[ÉVÉáÉìÇ…ëŒÇµÇƒÉçÅ[ÉJÉâÉCÉYçœÇ›ÇÃï∂éöóÒÇíÒãüÇ∑ÇÈÉIÉvÉVÉáÉìÇÉåÉìÉ_ÉâÇ…ó^ǶÇÈDZÇΔÇåàíËǵNjǵÇΩÅBQD3D 1.5.1 Ç…ÇÕÅAéüÇÃÇÊǧǻêVǵǢä÷êîÅAQ3RendererClass_GetNickNameString ǙdžÇËÇ‹Ç∑ÅB
/*
* Q3RendererClass_GetNickNameString
* ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™ÉåÉìÉ_ÉâñºÇÃï∂éöóÒÇéÊìæÇ∑ÇÈÇΩÇflÇ…égópÇ∑ÇÈÅB
* ÉåÉìÉ_ÉâÇÕDZÇÃï∂éöóÒÇÅAó·Ç¶ÇŒÉäÉ\Å[ÉXÇΔǵǃÅAÉçÅ[ÉJÉâÉCÉYǵÇΩå`éÆÇ≈
* ï€ë∂ÇµÇƒÇ®Ç©Ç»ÇØÇÍnjǻÇÁǻǢÅBDZÇÃï∂éöóÒÇÕÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇ…
* ëIëã@î\ (ó·Ç¶ÇŒÉÅÉjÉÖÅ[Ç≈) ÇíÒãüÇ∑ÇÈÅB
*
* åƒÇ—èoǵÇÃåãâ ÅAï‘Ç≥ÇÍÇΩï∂éöóÒÇ™ nil ÇÃèÍçáÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅA
* ÉåÉìÉ_ÉâÇÃÉNÉâÉXñºÇégópǵǃLJÇÊÇ¢ÅBÉNÉâÉXñºÇÕÉçÅ[ÉJÉâÉCÉYÇ≈ǴǻǢÇÃÇ≈ÅA
* Ç‹Ç∏ïKÇ∏ñºëOÇÃï∂éöóÒÇéÊìæÇ∑ÇÈÇÊÇ§Ç…ÇµÇ»ÇØÇÍnjǻÇÁǻǢÅB
*/
TQ3Status Q3RendererClass_GetNickNameString(
   TQ3ObjectType rendererClassType,
   TQ3ObjectClassNameString rendererClassString
);


DZÇÃåƒÇ—èoǵÇ≈ÉåÉìÉ_ÉâÇãLèqÇ∑ÇÈï∂éöóÒÇéÊìæÇµÇ‹Ç∑ÅBDZÇÍÇÉÅÉjÉÖÅ[Ç‚ÅAǪÇÃëºÇÃÉÜÅ[ÉUÉCÉìÉ^ÉtÉFÅ[ÉXÇÃóvëfÇ…îzíuÇ∑ÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBQ3ObjectHierarchy_GetSubClassData ä÷êîÇÕÉåÉìÉ_ÉâÇÉ\Å[ÉgÇπÇ∏Ç…ï‘Ç∑ÇÃÇ≈ÅAÉåÉìÉ_ÉâÇÃÉäÉXÉgÇÕé©ï™Ç≈É\Å[ÉgÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅB

ïKóvÇ»ÉRÅ[ÉhÇÕDZÇÍÇæÇØÇ≈Ç∑ÅBÇ–ÇΔǬDžNjÇΔÇflǃǛNjǵÇÂǧÅBéüÇÃÉãÅ[É`ÉìÇÕÅAÉÅÉjÉÖÅ[ÉnÉìÉhÉãÇó^ǶÇÈÇΔÅAÇ∑Ç◊ǃÇÃÉCÉìÉXÉgÅ[ÉãçœÇ›ÇÃÉåÉìÉ_ÉâÇÉÅÉjÉÖÅ[Ç…ë}ì¸ÇµÇ‹Ç∑ÅB
#define kMaxRendererCount 10
static TQ3ObjectType pTypes[ kMaxRendererCount ] ;
#define mRendererMenu 5    /* ÉåÉìÉ_ÉâÉÅÉjÉÖÅ[ÇÃíËã` */

void SetUpRendererMenu( void )
{
  MenuHandle theMenu ;
  TQ3SubClassData subClassData;
  TQ3ObjectType *classPointer;
  short i, pRendererCount;
  TQ3ObjectClassNameString objectClassName;
  TQ3ObjectClassNameString objectClassString ;

      theMenu = GetMHandle(mRendererMenu);
      Q3ObjectHierarchy_GetSubClassData(kQ3SharedTypeRenderer,
                                        &subClassData);
      classPointer = subClassData.classTypes;
      pRendererCount = 0;
      i = subClassData.numClasses;
      while( i-- > 0 && pRendererCount <= kMaxRendererCount) {
          /*
          * " îƒóp " ÉåÉìÉ_ÉâÇÕì‡ïîÇ≈égópÇ≥ÇÍÇÈLJÇÃÇ≈ÅAï`âÊÇÕÇ≈ǴǻǢÇΩÇflÅA
          * ÉÜÅ[ÉUÉCÉìÉ^ÉtÉFÅ[ÉXçÄñ⁄Ç…ÇÕï\é¶ÇµÇ»Ç¢ÅB
          */
          if( *classPointer != kQ3RendererTypeGeneric )
          {
              Q3RendererClass_GetNickNameString(*classPointer,
                                                objectClassString );
              if( objectClassString[0] == '\0' )
              {
                  /* ÉåÉìÉ_ÉâÇÕñºëOÇï‘Ç≥ǻǢÇÃÇ≈ÅAÉNÉâÉXñºÇégópÇ∑ÇÈÅB */
                  Q3ObjectHierarchy_GetStringFromType(*classPointer,
                                                      objectClassName);
                  AppendMenu(theMenu,c2pstr((char *)objectClassName));
                  pTypes[pRendererCount++] = *classPointer ;
              }
              else
              {
                  AppendMenu(theMenu,c2pstr(objectClassString));
                  pTypes[pRendererCount++] = *classPointer ;
              }
          }
      classPointer++ ;
      }

      pTypes[pRendererCount] = NULL ;
      Q3ObjectHierarchy_EmptySubClassData( &subClassData ) ;
}


è„ÇÃó·Ç≈íçà”ÇµÇ»ÇØÇÍnjǻÇÁǻǢèdóvÇ»ì_Ç™ 3 ǬdžÇËÇ‹Ç∑ÅBÇ‹Ç∏ÅAÉåÉìÉ_ÉâÇ©ÇÁñºëOÇ™éÊìæÇ≈ǴǻǢèÍçáÇÕÅAë„ÇÌÇËÇ…ÉNÉâÉXñºÇégǧDZÇΔÇ≈Ç∑ÅBéüÇ…ÅAkQ3RendererTypeGeneric É^ÉCÉvÇÃÉåÉìÉ_ÉâÇñ≥éãǵǃǢÇÈDZÇΔÇ…íçà”ǵǃÇ≠ÇæÇ≥Ç¢ÅBDZÇÍÇÕÉ_É~Å[ÇÃÉåÉìÉ_ÉâÇ≈ÅAâΩLJÉåÉìÉ_ÉäÉìÉOǵNjÇπÇÒÅBÉåÉìÉ_ÉäÉìÉOÇ…égópÇ≈ǴǻǢLJÇÃÇÉÅÉjÉÖÅ[Ç…â¡Ç¶ÇƒÇÕÇ¢ÇØÇ‹ÇπÇÒÅB3 ǬÇflÇ…ÅAÉÅÉjÉÖÅ[ÇÃÉCÉìÉfÉbÉNÉXÇ…çáÇÌÇπǃÅAÉåÉìÉ_ÉâÉ^ÉCÉvÇ pTypes îzóÒÇ…ï€ä«ÇµÇƒÇ¢ÇÈì_Ç…íçà”ǵǃÇ≠ÇæÇ≥Ç¢ÅBDZǧǵǃǮÇ≠ÇΔÅAdžÇΔÇ≈ÉÜÅ[ÉUÇÃëIëDžǵÇΩǙǡǃÉåÉìÉ_ÉâÇê›íËÇ∑ÇÈç€Ç…îÒèÌÇ…ï÷óòÇ≈Ç∑ÅB

ç≈å„Ç…ÅAQ3ObjectHierarchy_EmptySubClassData ÇåƒÇ—èoǵǃÅAÉVÉXÉeÉÄÇ…ÉCÉìÉXÉgÅ[ÉãçœÇ›ÇÃÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÃñ‚Ç¢çáÇÌÇπÇÃç€Ç…äÑÇËìñǃÇΩÉÅÉÇÉäÇâï˙ǵǃǢÇÈì_Ç…íçñ⁄ǵǃÇ≠ÇæÇ≥Ç¢ÅB

ÉåÉìÉ_ÉâÇÃê›íË

ÉCÉìÉXÉgÅ[ÉãçœÇ›ÉåÉìÉ_ÉâÇÃÉäÉXÉgÇï\é¶Ç∑ÇÈÉÅÉjÉÖÅ[Çç\ízǵǃǵNjǶnjÅAÉÜÅ[ÉUÇÃëIëÇ…äÓÇ√ǢǃÉåÉìÉ_ÉâÇÃê›íËÇçsǧÇÃÇÕä»íPÇ≈Ç∑ÅBDZÇÃó·ÇÕïKóvà»è„Ç…ï°éGÇ≈Ç∑Ç™ÅAǪÇÍÇÕ QD3D ÉrÉÖÅ[ÉAÅEÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÉåÉìÉ_ÉâÇê›íËÇ∑ÇÈèÍçáÇéÊÇËè„Ç∞ÇΩÇΩÇflÇ≈Ç∑ÅBäÓñ{ìIÇ»ïîï™ÇÕÇ∑Ç◊ǃÇÃéÌófiÇÃÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ìØÇ∂Ç≈Ç∑ÅB

#define kMaxRendererCount 10
static TQ3ObjectType pTypes[ kMaxRendererCount ] ;

typedef struct {
    TQ3ViewerObject fViewer; /* DZÇÃï∂èëÇÃÉrÉÖÅ[ÉAÇ÷ÇÃéQèΔÇï€ë∂Ç∑ÇÈ */
    .
    .
    .
} ViewerDocument, *ViewerDocumentPtr, **ViewerDocumentHdl;

/*
* ÉåÉìÉ_ÉâÉÅÉjÉÖÅ[ÇÃÉÅÉjÉÖÅ[ÉRÉ}ÉìÉhÇèàóùÇ∑ÇÈ
*/
void HandleRendererMenu( short menuItem )
{
  ViewerDocumentHdl theViewerDocumentHdl ;
  WindowPtr theWindow ;
  TQ3ViewerObject theViewer ;
  OSErr theError ;
  TQ3ViewObject myView ;
  TQ3Status myStatus ;
  TQ3RendererObject myRenderer ;

      theWindow = FrontWindow() ;
      if( theWindow != NULL )
      {
          /*
          * ÉEÉCÉìÉhÉEÇà long ÇÃéQèΔíËêîÇ©ÇÁÅAÉrÉÖÅ[ÉAÇÃï∂èëÇÃÉfÅ[É^ç\ë¢ëÃ
          * Ç÷ÇÃéQèΔÇéÊìæÇµÇƒÅAǪÇÍÇìKêÿÇ»É^ÉCÉvÇ…ÉLÉÉÉXÉgÇ∑ÇÈÅB
          * éQèΔÇ™éÊìæÇ≈ǴǻǢèÍçá (null ÇÃèÍçá) ÇÕDZDZÇ≈é~ÇflÇÈÅB
          */
          theViewerDocumentHdl =
             (ViewerDocumentHdl)GetWRefCon(theWindow) ;
          if(theViewerDocumentHdl == NULL)
              return ;

          /* ÉfÅ[É^ç\ë¢ëÃÇ©ÇÁÉrÉÖÅ[ÉAÉIÉuÉWÉFÉNÉgÇ÷ÇÃéQèΔÇéÊÇËèoÇ∑ */
          theViewer = (**theViewerDocumentHdl).fViewer ;
          if(theViewer == NULL)
              return ;
          myRenderer = Q3Renderer_NewFromType( pTypes[ menuItem - 1 ] );

          /*
          * ÉrÉÖÅ[ÇÃÉåÉìÉ_ÉâÇê›íËÇ∑ÇÈ
          */
          myView = Q3ViewerGetView( theViewer );
          if( myView != NULL && myRenderer != NULL )
          {
            /* ÉåÉìÉ_ÉâÇÅAè„Çà switch ï∂Ç≈çÏê¨ÇµÇΩLJÇÃÇ…ê›íËÇ∑ÇÈ */
              myStatus = Q3View_SetRenderer(myView, myRenderer) ;
              /* ÉåÉìÉ_ÉâÇÃê›íËÇ™èIÇÌÇ¡ÇΩÇÃÇ≈ÅAÉåÉìÉ_ÉâÇ÷ÇÃéQèΔÇ
                 îjä¸Ç∑ÇÈDZÇΔÇ™Ç≈Ç´ÇÈ */
              myStatus = Q3Object_Dispose( myRenderer ) ;
              /* ǪǵǃÅAÉrÉÖÅ[ÉAÇÃì‡óeï\é¶óÃàÊÇï`Ç´íºÇ∑ */
              theError = Q3ViewerDrawContent( theViewer ) ;
          }
      }
}



ÉåÉìÉ_ÉâÇÃê›íËïœçXÇÃÉTÉ|Å[Ég

ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇÉTÉ|Å[ÉgÇ∑ÇÈèÍçáÅAÉåÉìÉ_ÉâÇÃê›íËïœçXÉ_ÉCÉAÉçÉOÇ…ÉAÉNÉZÉXÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBDZÇÍÇÕÅAÉåÉìÉ_ÉâÇÃï`âÊï˚ñ@Çê›íËÇ∑ÇÈÉ_ÉCÉAÉçÉOÇ≈Ç∑ÅB

QD3D Çà Q3Renderer_HasModalConfigure ä÷êîÇåƒÇ—èoǵǃÅAÉåÉìÉ_ÉâÇ™ÉÇÅ[É_ÉãÇ»ê›íËïœçXÉ_ÉCÉAÉçÉOÇéùǡǃǢÇÈǩǫǧǩÇí≤Ç◊ÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBéÑÇΩÇøÇÕÅAQD3D 1.5.1 Ç≈ÇÕÅADZÇÃä÷êîÇÉèÉCÉÑÉtÉåÅ[ÉÄÉåÉìÉ_ÉâDžLJÉCÉìÉ^ÉâÉNÉeÉBÉuÉåÉìÉ_ÉâDžLJé¿ëïǵNjÇπÇÒÇ≈ǵÇΩÇ™ÅAQD3D ÇÃÉäÉäÅ[ÉX 1.5.3 à»ç~Ç…ÇÕé¿ëïÇ∑ÇÈó\íËÇ≈Ç∑ÅBéüÇÃÉRÅ[ÉhÇÕÅAQ3Renderer_HasModalConfigure ä÷êîÇÃégópñ@Çé¶ÇµÇΩLJÇÃÇ≈Ç∑ÅB

{
 TQ3RendererObject qd3dRenderer;
 TQ3ViewObject qd3dView;
 TQ3Status qd3dStatus;
 TQ3Boolean qd3dCanceled;
 TQ3DialogAnchor qd3dAnchor ;

    // ÉåÉìÉ_ÉâÇéÊìæÇ∑ÇÈ
    qd3dView = Q3ViewerGetView(theViewer);
    qd3dStatus = Q3View_GetRenderer(qd3dView, &qd3dRenderer);

    // ê›íËïœçXÉ_ÉCÉAÉçÉOÇç\ízÇ∑ÇÈ
    if (Q3Renderer_HasModalConfigure(qd3dRenderer))
    {
        #if 0
            /* ÉÇÅ[É_ÉãÇ…Ç∑ÇÈ */
             qd3dAnchor.clientEventHandler = NULL;
        #else
           /* ÉCÉxÉìÉgÉnÉìÉhÉâÇìnÇ∑ÇΔÅAà⁄ìÆâ¬î\Ç»ÉÇÅ[É_ÉãÇ…Ç»ÇÈ */
           qd3dAnchor.clientEventHandler = HandleEvent ;
        #endif

        qd3dStatus = Q3Renderer_ModalConfigure(qd3dRenderer,
                                                qd3dAnchor,
                                                &qd3dCanceled);
    }

    // ïsóvǻLJÇÃÇéÊÇËèúÇ≠
    qd3dStatus = Q3Object_Dispose(qd3dRenderer);
};


è„ÇÃÉRÅ[ÉhÇ≈íçñ⁄Ç∑Ç◊Ç´Ç»ÇÃÇÕÅAclientEventHandler ÉtÉBÅ[ÉãÉhÇ≈Ç∑ÅBÉ_ÉCÉAÉçÉOÇ™ÉÇÅ[É_ÉãÇ≈ÇÊÇØÇÍÇŒÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕDZÇÃÉtÉBÅ[ÉãÉhÇ nil Ç…ê›íËǵNjÇ∑ÅBÉ_ÉCÉAÉçÉOÇà⁄ìÆâ¬î\DžǵÇΩÇØÇÍÇŒÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃÉCÉxÉìÉgÉnÉìÉhÉâÇ÷ÇÃéQèΔÇìnÇ∑ïKóvǙdžÇËÇ‹Ç∑ÅB

Ç‹ÇΩÅAÉAÉbÉvÉãÉÅÉjÉÖÅ[ÇÃÇ§ÇøÅu... DžǬǢǃÅvÉÅÉjÉÖÅ[ÇÕëIëïsâ¬Ç…ǵÅAǪÇÍà»äOÇÕëIëâ¬î\Ç…Ç∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBÇ≥ÇÁÇ…ÅAï“èWÉÅÉjÉÖÅ[à»äOÇÃÉÅÉjÉÖÅ[ÇÕÇ∑Ç◊ǃëIëïsâ¬Ç…ǵÅAï“èWÉÅÉjÉÖÅ[ÇÃÇ§ÇøÅAéÊÇËè¡ÇµÅAÉJÉbÉgÅAÉRÉsÅ[ÅAÉyÅ[ÉXÉgÅAè¡ãéÇÕëIëâ¬î\DžǵÅAǪÇÍà»äOÇÕëIëïsâ¬Ç…ǵNjÇ∑ÅBDZÇÍÇéüÇÃÉRÅ[ÉhÇÃífï–Ç≈é¶ÇµÇ‹Ç∑ÅB

void SpinDialog_ConfigureRenderer(void)
{
    TQ3ViewObject view;
    TQ3RendererObject renderer;
    TQ3DialogAnchor dialogAnchor;
    TQ3Boolean canceled;
    MenuHandle m;

        SpinView_GetView(&view);
        Q3View_GetRenderer(view, &renderer);
        if (Q3Renderer_HasModalConfigure(renderer)) {
            dialogAnchor.clientEventHandler = SpinEventHandlerWrapper;
            m = GetMHandle(kMenu_Apple);
            SpinMenu_EnableItem(m, kAppleMenu_About, false);
            m = GetMHandle(kMenu_File);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_Edit);
            SpinMenu_EnableItem(m, kEditMenu_Undo, true);
            SpinMenu_EnableItem(m, kEditMenu_Cut, true);
            SpinMenu_EnableItem(m, kEditMenu_Copy, true);
            SpinMenu_EnableItem(m, kEditMenu_Paste, true);
            SpinMenu_EnableItem(m, kEditMenu_Clear, true);
            SpinMenu_EnableItem(m, kEditMenu_Preferences, false);
            m = GetMHandle(kMenu_Commands);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_Dialog);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_View);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_Geometry);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_Complex);
            SpinMenu_EnableItem(m, 0, false);
            m = GetMHandle(kMenu_Demos);
            SpinMenu_EnableItem(m, 0, false);
            DrawMenuBar();
            Q3Renderer_ModalConfigure(renderer, dialogAnchor, &canceled);
            m = GetMHandle(kMenu_Apple);
            SpinMenu_EnableItem(m, kAppleMenu_About, true);
            m = GetMHandle(kMenu_File);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_Commands);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_Dialog);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_View);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_Geometry);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_Complex);
            SpinMenu_EnableItem(m, 0, true);
            m = GetMHandle(kMenu_Demos);
            SpinMenu_EnableItem(m, 0, true);
            SpinMenu_Update();
            DrawMenuBar();
        }
        else {
            Alert(kNoModalConfigureALRT, NULL);
        }
}


ÉvÉâÉOÉCÉìÉåÉìÉ_ÉâÇ…ÇÊÇÈÉåÉìÉ_ÉâñºÇÃÉTÉ|Å[Ég

ÉåÉìÉ_ÉâÇÃÉRÅ[ÉhÇèëÇ≠êlÇÕÇŸÇΔÇÒǫǢǻǢÇ≈ǵÇÂǧÅBñcëÂÇ»ó ÇÃêÍñÂíméØÇΔéûä‘ÇóvÇ∑ÇÈÇ©ÇÁÇ≈Ç∑ÅBǵǩǵÅAéüÇÃÇÊǧDžÉTÉìÉvÉãÉåÉìÉ_ÉâÇÃÉTÉìÉvÉãÉRÅ[ÉhÇ… (QD3D SDK Ç©ÇÁéùǡǃǴǃ) èCê≥Çâ¡Ç¶ÇÍÇŒÅAÉoÉbÉtÉ@Ç…ä‹Ç‹ÇÍǃǢÇÈÉåÉìÉ_ÉâñºÇÃï∂éöóÒÇéÊÇËèoÇ∑DZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅB

extern AliasHandle SRgAliasHandle;
#define SR_NAME_RESOURCE  16211 /* ÉRÅ[ÉhíÜÇÃÉåÉìÉ_ÉâñºÇÃ
                                   ÉäÉ\Å[ÉXï∂éöóÒÇà ID */

TQ3Status SR_GetNameString(
    unsigned char *dataBuffer,
    unsigned long bufferSize,
    unsigned long *actualDataSize)
{
 TQ3Status status = kQ3Success ;
 Boolean wasChanged;
 FSSpec fileSpec;
 OSErr macErr;
 Str255 tempBuffer ;
 short SRgOldResFile, SRgResFile;

     /*
     * DZÇÃÉåÉìÉ_ÉâÇÃÉäÉ\Å[ÉXÉtÉ@ÉCÉãÇå©Ç¬ÇØÅAÉäÉ\Å[ÉXÉtÉ@ÉCÉãÇäJÇ´ÅA
     * ÉåÉìÉ_ÉâñºÇÃï∂éöóÒÇå©Ç¬ÇØÅAÉäÉ\Å[ÉXÉtÉ@ÉCÉãÇï¬Ç∂ÅAìnÇ≥ÇÍÇΩ
     * ÉoÉbÉtÉ@Ç…ï∂éöóÒÇï‘Ç∑ÅB
     */
     SRgOldResFile = CurResFile();
     if ((SRgAliasHandle != NULL) || (*SRgAliasHandle != NULL)) {
         macErr = ResolveAlias(NULL, SRgAliasHandle, &fileSpec,
                               &wasChanged);
         if (macErr == noErr) {
             SRgResFile = FSpOpenResFile(&fileSpec, fsRdPerm);
             if (SRgResFile != -1) {
                 *actualDataSize = 0L;
                 GetIndString( tempBuffer, SR_NAME_RESOURCE, 1 ) ;
                 /* ÉoÉbÉtÉ@ññîˆÇÃïsóvïîï™ÇêÿÇËéÃǃÇÈ */
                 *actualDataSize = (tempBuffer[0] bufferSize) ?
                                    bufferSize : tempBuffer[0] ;
                 if (dataBuffer != NULL) {
                   /* ÉäÉ\Å[ÉXÉ}ÉlÅ[ÉWÉÉÇ©ÇÁï‘Ç≥ÇÍÇΩÉpÉXÉJÉãï∂éöóÒÇ©ÇÁ
                      ÉRÉsÅ[Ç∑ÇÈ */
                     memcpy((char *)dataBuffer,
                     (char *) &tempBuffer[1],
                     *actualDataSize );
                     /* ǪǵǃÅAï∂éöóÒÇÃèIí[Çê›íËÇ∑ÇÈ */
                     dataBuffer[*actualDataSize] = '\0' ;
                 }
                     CloseResFile(SRgResFile);
                     UseResFile(SRgOldResFile);
             }
             else {
                 Q3XMacintoshError_Post(ResError());
                 status = kQ3Failure;
             }
         }
         else {
             Q3XMacintoshError_Post(macErr);
             status = kQ3Failure;
         }
     }
     else {
         status = kQ3Failure;  /* null ÉGÉCÉäÉAÉX */
     }

     if( status == kQ3Failure )
     {
     *actualDataSize = 0L ;
     dataBuffer = NULL ;
     }

     return (status);
}


è„ãLÇÃÉRÅ[ÉhÇ≈èdóvÇ»ÇÃÇÕÅAÉåÉìÉ_ÉâÉtÉ@ÉCÉãÇ÷ÇÃéQèΔÇ (SRgAliasHandle Ç…) ï€ë∂ǵǃÅAÉäÉ\Å[ÉXÉtÉHÅ[ÉNÇäJÇØÇÈÇÊǧDžÇ∑ÇÈDZÇΔÇ≈Ç∑ÅBDZÇÃó·Ç≈ÇÕÅAÉäÉ\Å[ÉXÇï∂éöóÒÉäÉXÉgÇÃ'STR#'É^ÉCÉvÉäÉ\Å[ÉXÇΔǵǃÉtÉ@ÉCÉãÇ…ì¸ÇÍÇÈDZÇΔDžǵNjǵÇΩÅBDZǧÇ∑ÇÍÇŒÅA1 ÉoÉCÉgï∂éöÇ‚ 2 ÉoÉCÉgï∂éöÇÃï°êîÇÃÉçÅ[ÉJÉâÉCÉYï∂éöóÒÇï€ë∂ǵǃÅAÉåÉìÉ_ÉâǙǪÇÍÇÁÇêÿÇËë÷ǶÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBÇ‡ÇøÇÎÇÒÅAï∂éöóÒÇÕ 1 Ç¬ÇæÇØéùÇΩÇπÅAÉåÉìÉ_ÉâÇÃÉ}Å[ÉPÉbÉgÇ…çáÇÌÇπǃÉçÅ[ÉJÉâÉCÉYÇ∑ÇÈDZÇΔLJÇ≈Ç´Ç‹Ç∑ÅB

è„ãLÇÃÉRÅ[ÉhÇÕÉåÉìÉ_ÉâÇÃÉçÅ[ÉhÇÃç€Ç…ïKÇ∏åƒÇ—èoÇ≥ÇÍÇÈÇÊÇ§Ç…ÇµÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅBǪÇÃÇΩÇflÇ…ÇÕÅAÉåÉìÉ_ÉâÇÃÉÅÉ^ÉnÉìÉhÉâÇïœçXÇµÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅBïœçXÇÕîÒèÌÇ…ä»íPÇ≈ÅAéüÇÃÇÊǧDžÅAñºëOÇéÊìæÇ∑ÇÈÉãÅ[É`ÉìÇéQèΔÇ∑ÇÈ case ï∂Çí«â¡Ç∑ÇÈÇæÇØÇ≈Ç∑ÅB

/*
* ÉåÉìÉ_ÉâñºÇÃï∂éöóÒ
*/
case kQ3XMethodTypeRendererGetNickNameString: {
   return (TQ3XFunctionPointer) SR_GetNameString;
break;
}



Renderer.h ÇÃïœçXì_Çå©ÇÈÇΔÇÌÇ©ÇËÇ‹Ç∑ÅB

/*
* kQ3XMethodTypeRendererGetNickNameString
*
* ÉÅÉjÉÖÅ[ǻǫÇÃÉÜÅ[ÉUÉCÉìÉ^ÉtÉFÅ[ÉXçÄñ⁄Ç…ï\é¶Ç∑ÇÈÇΩÇflÅA
* ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™ÉåÉìÉ_ÉâÇÃñºëOÇéÊìæÇ≈Ç´ÇÈÇÊǧDžÇ∑ÇÈÅB
*
* dataBuffer Ç™ NULL ÇÃèÍçáÅAactualDataSize ÇÕñºëOÇï€ë∂Ç∑ÇÈÇÃÇ…ïKóvÇ»
* ÉfÅ[É^ÉoÉbÉtÉ@ÇÃÉTÉCÉYÇÉoÉCÉgêîÇ≈ï‘Ç∑
*
* bufferSize ÇÕÅAdataBuffer Ç™éwÇ∑ÉÅÉÇÉäÉuÉçÉbÉNÇÃé¿ç€ÇÃÉTÉCÉY
*
* actualDataSize - ä÷êîÇÃñflÇËÇ≈ÉoÉbÉtÉ@Ç…èëÇ´çûÇ‹ÇÍÇΩé¿ç€ÇÃÉoÉCÉgêîÅB
* dataBuffer Ç™ NULL ÇÃèÍçáÇÕïKóvÇ» dataBuffer ÇÃÉTÉCÉY
*
* ÉIÉvÉVÉáÉì
*/

#define kQ3XMethodTypeRendererGetNickNameString \
   Q3_METHOD_TYPE('r','d','n','s')
typedef TQ3Status (QD3D_CALLBACK *TQ3XRendererGetNickNameStringMethod)(
   unsigned char *dataBuffer,
   unsigned long bufferSize,
   unsigned long *actualDataSize);



óvñÒ

ÉfÉxÉçÉbÉpÇÕÅAQD3D ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ïKÇ∏ÉvÉâÉOÉCÉìÇÃÉTÉ|Å[ÉgÇíÒãüǵÇΩÇ¢ÇΔévǧÇ≈ǵÇÂǧÅBÉvÉâÉOÉCÉìÇìKêÿÇ…ÉTÉ|Å[ÉgÇ∑ÇÈÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕÅAåªç›Ç†ÇÈÉåÉìÉ_ÉâÇ‹ÇΩÇÕè´óàìoèÍÇ∑ÇÈÉTÅ[ÉhÉpÅ[ÉeÉBÇÃÉåÉìÉ_ÉâÇóòópÇ≈Ç´ÅAÉvÉâÉOÉCÉìÇÉTÉ|Å[ÉgǵǻǢÉAÉvÉäÉPÅ[ÉVÉáÉìÇÊÇËà≥ì|ìIÇ…óLóòÇ…Ç»ÇÈÇ©ÇÁÇ≈Ç∑ÅB

QD3D ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÃÉvÉâÉOÉCÉìÇÃÉTÉ|Å[ÉgÇÕîÒèÌÇ…ä»íPÇ≈Ç∑ÅBÉvÉâÉOÉCÉìÇÉTÉ|Å[ÉgÇ∑ÇÈÇΩÇflÇ…ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ™çsǧïKóvÇÃdžÇÈçÏãΔÇÕéüÇÃí ÇËÇ≈Ç∑ÅB

  • égópâ¬î\Ç»ÉåÉìÉ_ÉâÇ QD3D Ç…ñ‚Ç¢çáÇÌÇπÇÈÅB
  • égópâ¬î\Ç»ÉåÉìÉ_ÉâÇÃÉäÉXÉgÇç\ízǵÅAÉÜÅ[ÉUÇ…ëIëÇ≥ÇπÇÈÅB
  • ÉåÉìÉ_ÉâÇ™ÉCÉìÉ^ÉâÉNÉeÉBÉuÇ©Çí≤Ç◊ÇÈÅB
  • ÉÜÅ[ÉUÇÃëIëÇ…âûÇ∂ǃÅAégópÇ∑ÇÈÉåÉìÉ_ÉâÇê›íËÇ∑ÇÈÅB


éQçlï∂å£

Åw3D Graphics Programming With QuickDraw 3DÅx(Addison-Wesley äß)

çXêVì˙: 1997 îN 10 åé 31 ì˙